import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter_common_utils/src/log/log.dart';
import 'package:path_provider/path_provider.dart';

extension CUFileExtension on File {
  /// 异步创建文件
  Future<File> createX() async {
    // 如果文件不存在，则创建它
    if (!(await exists())) {
      return create(recursive: true); // 设置 recursive: true 确保所有必要的父目录都被创建
    }
    return this;
  }

  /// 同步创建文件
  File createSyncX() {
    // 如果文件不存在，则创建它
    if (!existsSync()) {
      createSync(recursive: true); // 设置 recursive: true 确保所有必要的父目录都被创建
    }
    return this;
  }

  /// 读取文件
  String? readAsStringSyncX({Encoding encoding = utf8}) {
    try {
      if (existsSync()) {
        return readAsStringSync(encoding: encoding);
      }
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
    return null;
  }

  /// 读取文件
  Future<String?> readAsStringX({Encoding encoding = utf8}) async {
    try {
      if (await exists()) {
        return await readAsString(encoding: encoding);
      }
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
    return null;
  }

  /// 读取文件
  Uint8List? readAsBytesSyncX() {
    try {
      if (existsSync()) {
        return readAsBytesSync();
      }
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
    return null;
  }

  /// 读取文件
  Future<Uint8List?> readAsBytesX() async {
    try {
      if (await exists()) {
        return await readAsBytes();
      }
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
    return null;
  }

  /// 读取文件
  List<String> readAsLinesSyncX({Encoding encoding = utf8}) {
    try {
      if (existsSync()) {
        return readAsLinesSync(encoding: encoding);
      }
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
    return [];
  }

  /// 读取文件
  Future<List<String>> readAsLinesX({Encoding encoding = utf8}) async {
    try {
      if (await exists()) {
        return await readAsLines(encoding: encoding);
      }
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
    return [];
  }

  // 写入字符串
  Future<bool> writeAsStringX(
    String content, {
    FileMode mode = FileMode.write,
    bool flush = false,
    bool isAutoCreate = false,
  }) async {
    try {
      if (isAutoCreate) {
        await createX();
      }
      await writeAsString(content, mode: mode, flush: flush);
      return true;
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
      return false;
    }
  }

  // 写入字符串
  bool writeAsStringSyncX(
    String content, {
    FileMode mode = FileMode.write,
    bool flush = false,
    bool isAutoCreate = false,
  }) {
    try {
      if (isAutoCreate) {
        createSyncX();
      }
      writeAsStringSync(content, mode: mode, flush: flush);
      return true;
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
      return false;
    }
  }

  //写入Uint8List
  Future<bool> writeAsBytesX(
    Uint8List content, {
    FileMode mode = FileMode.write,
    bool flush = false,
    bool isAutoCreate = false,
  }) async {
    try {
      if (isAutoCreate) {
        await createX();
      }
      await writeAsBytes(content, mode: mode, flush: flush);
      return true;
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
      return false;
    }
  }

  //写入Uint8List
  bool writeAsBytesSyncX(
    Uint8List content, {
    FileMode mode = FileMode.write,
    bool flush = false,
    bool isAutoCreate = false,
  }) {
    try {
      if (isAutoCreate) {
        createSyncX();
      }
      writeAsBytesSync(content, mode: mode, flush: flush);
      return true;
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
      return false;
    }
  }

  //同步删除文件
  void deleteSyncX() {
    try {
      if (!existsSync()) {
        return;
      }
      deleteSync();
    } catch (e, s) {
      LogUtils.e("", error: e, stackTrace: s);
    }
  }
}

class FileUtils {
  static String cacheDir = '';

  static Future<void> init() async {
    await cacheDirAsync;
    return;
  }

  // 缓存目录
  static Future<String> get cacheDirAsync async {
    if (kIsWeb) return "";
    final directory = await getApplicationCacheDirectory();
    cacheDir = directory.path;
    return directory.path;
  }

  static Future<void> createMkdirs(String path) async {
    if (kIsWeb) return;
    await Directory(path).create(recursive: true);
  }

  static void deleteFile(File file) {
    if (kIsWeb) return;
    file.deleteSyncX();
  }

  ///裁剪文件大小
  /// [maxSize] 最大多少多少
  /// [keepSize] 保留多少
  static Future<bool> trimFile(File file, {int maxSize = 50 * 1024 * 1024, int keepSize = 10 * 1024 * 1024}) async {
    try {
      // 检查文件是否存在
      if (!await file.exists()) {
        return false;
      }
      // 获取文件大小
      final length = await file.length();
      // 检查是否需要裁剪
      if (length > maxSize) {
        // 创建临时文件
        final tempFile = File('${file.path}.tmp');
        // 使用流式处理避免内存溢出
        final input = file.openRead(length - keepSize);
        final output = tempFile.openWrite();
        // 写入剩余数据
        await input.pipe(output);
        await output.close();
        // 替换原文件
        await tempFile.rename(file.path);
        return true;
      } else {
        return true;
      }
    } catch (e, s) {
      LogUtils.e("trimFile error", error: e, stackTrace: s);
      return false;
    }
  }
}
